package com.itlong.cloud.controller.miniprogram;

import com.itlong.cloud.POJO.DTO.app.AppTouristDTO;
import com.itlong.cloud.POJO.DTO.app.MiniScanQrCodePassDTO;
import com.itlong.cloud.POJO.DTO.operate.OperateBusinessChargeDTO;
import com.itlong.cloud.POJO.DTO.property.IotCloudEntranceStateDTO;
import com.itlong.cloud.POJO.PO.GuestUserHistoryPO;
import com.itlong.cloud.POJO.PO.ProjectPO;
import com.itlong.cloud.POJO.VO.MessageVO;
import com.itlong.cloud.POJO.VO.app.AppUserCacheVO;
import com.itlong.cloud.POJO.VO.app.AppUserOwnProjectVO;
import com.itlong.cloud.POJO.VO.miniprogram.MiniProgramMyEquipListVO;
import com.itlong.cloud.POJO.VO.miniprogram.MiniProgramUserRoomInfoVO;
import com.itlong.cloud.POJO.VO.miniprogram.MiniScanQrCodePassVO;
import com.itlong.cloud.POJO.VO.operate.OperateDeviceQRCodeInfoVO;
import com.itlong.cloud.POJO.VO.operate.OperateProjectDetailVO;
import com.itlong.cloud.POJO.VO.operate.OperatePropertyInformationGetVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.abstracts.BaseController;
import com.itlong.cloud.annotation.LoggerInfo;
import com.itlong.cloud.constants.LogDescConstant;
import com.itlong.cloud.constants.RedisConstant;
import com.itlong.cloud.enumerate.CloudEntranceOpenTypeEnum;
import com.itlong.cloud.enumerate.DataStatusEnum;
import com.itlong.cloud.enumerate.IotDeviceStatusEnum;
import com.itlong.cloud.enumerate.ecode.AppErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.BaseErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.MiniProgramErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode_en.BaseErrorCodeEnumEN;
import com.itlong.cloud.equip.app.IAppDevicePassRecordServiceClient;
import com.itlong.cloud.equip.app.IAppDeviceServiceClient;
import com.itlong.cloud.equip.commons.ICloudEntranceServiceClient;
import com.itlong.cloud.equip.miniprogram.IMiniProgramEquipServiceClient;
import com.itlong.cloud.iottp.IIotServerServiceClient;
import com.itlong.cloud.paymenthub.IOperateBusinessChargeServiceClient;
import com.itlong.cloud.project.app.IAppProjectServiceClient;
import com.itlong.cloud.project.operate.IOperateProjectServiceClient;
import com.itlong.cloud.project.operate.IOperatePushInfoServiceClient;
import com.itlong.cloud.project.property.IPropertyAccountServiceClient;
import com.itlong.cloud.service.RedisService;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.user.app.IAppMineServiceClient;
import com.itlong.cloud.user.app.IAppPadFaceServiceClient;
import com.itlong.cloud.user.app.IAppRegisterServiceClient;
import com.itlong.cloud.user.miniprogram.IMiniProgramLoginServiceClient;
import com.itlong.cloud.utils.date.DateUtil;
import com.itlong.cloud.utils.encrypt.Md5EncryptUtil;
import com.itlong.cloud.utils.encrypt.UserTokenUtil;
import com.itlong.cloud.utils.network.http.HttpProtocolUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <desc>
 *     小程序通行控制器
 * </desc>
 *
 * @create  2018/11/19
 */
@RestController
@RequestMapping("/record")
@RefreshScope
public class MiniprogramRecordController extends BaseController{

    private static final Logger LOG = LoggerFactory.getLogger(MiniprogramRecordController.class);

    //解析userId用
    @Value("${" + PlatformConstants.MINI_PROGRAM_USER_TOKEN_KEY + "}")
    public String MINI_PROGRAM_USER_TOKEN_KEY;

    //解密用
    @Value("${" + PlatformConstants.MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY + "}")
    public String MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY;

    @Autowired
    IAppProjectServiceClient iAppProjectServiceClient;

    @Autowired
    IOperateProjectServiceClient iOperateProjectServiceClient;

    //APP设备信息业务处理暴露接口
    @Autowired
    IAppDeviceServiceClient iAppDeviceServiceClient;

    @Autowired
    IAppMineServiceClient iAppMineServiceClient;

    @Autowired
    IOperatePushInfoServiceClient iOperatePushInfoServiceClient;

    @Autowired
    IAppRegisterServiceClient iAppRegisterServiceClient;

    @Autowired
    ICloudEntranceServiceClient iCloudEntranceServiceClient;

    @Autowired
    IMiniProgramLoginServiceClient userCache;

    @Autowired
    private RedisService redisService;

    @Autowired
    IIotServerServiceClient iIotServerServiceClient;

    @Autowired
    private IPropertyAccountServiceClient iPropertyAccountServiceClient;

    @Autowired
    IAppDevicePassRecordServiceClient iAppDevicePassRecordServiceClient;

    @Value("${" + PlatformConstants.PROPERTYMANAGE_WEB_URL + "}")
    public String PROPERTY_MANAGE_WEB_URL;

    @Autowired
    IAppPadFaceServiceClient iAppPadFaceServiceClient;

    @Autowired
    private IOperateBusinessChargeServiceClient iOperateBusinessChargeServiceClient;


    @Autowired
    IMiniProgramEquipServiceClient iMiniProgramEquipServiceClient;

    /**
     * <desc>
     *      获取所有项目id，项目名称
     * </desc>
     *
     * @param token
     * @return
     * @author Qiang.S
     * @createDate 2018/11/19
     */
    @RequestMapping(value = "/getAllProjects",method = RequestMethod.POST)
    @ResponseBody
    public Object getAllProjects(String token, String createTime, String sign){
        MessageVO messageVO;
        try{
            HttpServletRequest request= ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            token=request.getAttribute("token")==null?null:request.getAttribute("token").toString();
            createTime=request.getAttribute("createTime")==null?null:request.getAttribute("createTime").toString();
            sign=request.getAttribute("sign")==null?null:request.getAttribute("sign").toString();
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("createTime",createTime);
            //验证签名
            if(!Md5EncryptUtil.checkAppSignValue(params,sign,MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY)){
                return new MessageVO(MiniProgramErrorCodeEnum.MINI_PROGRAM_SIGN_ERR.getErrorCode());
            }
            ///解密拿到userId
            String userId = UserTokenUtil.tokenDecrypt(token, MINI_PROGRAM_USER_TOKEN_KEY);
            messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),iAppRegisterServiceClient.getUserOwnProjectsInfo(userId,"-1"));
        }catch ( Exception e){
            throw new DataAccessException("【小程序_通行版块】获取所有项目id，项目名称",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      根据定位获取最近的开通了游客模式的项目
     * </desc>
     *
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2020/04/30
     */
    @RequestMapping(value = "/getProjectByLocation", method = RequestMethod.POST)
    @ResponseBody
    public Object getProjectByLocation(String token, String longitude, String latitude, String createTime, String sign){
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            token = request.getAttribute("token") == null ? null : request.getAttribute("token").toString();
            longitude = request.getAttribute("longitude") == null ? null : request.getAttribute("longitude").toString();
            latitude = request.getAttribute("latitude") == null ? null : request.getAttribute("latitude").toString();
            createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
            sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
            //验签
            Map<String, String> params = new HashMap<>();
            params.put("longitude", longitude);
            params.put("latitude", latitude);
            params.put("createTime", createTime);
            if (!Md5EncryptUtil.checkAppSignValue(params, sign, MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY)) {
                return new MessageVO(MiniProgramErrorCodeEnum.MINI_PROGRAM_SIGN_ERR.getErrorCode());
            }
            if (StringUtils.isBlank(longitude) || StringUtils.isBlank(latitude)) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            AppTouristDTO appTouristDTO = new AppTouristDTO();
            appTouristDTO.setPosition(longitude + "," + latitude);
            Map<String, Object> data = iAppProjectServiceClient.getProjectByLocation(appTouristDTO);
            if (data.get("projectId") != null && StringUtils.isNotBlank(data.get("projectId").toString())) {
                ///解密拿到userId
                String userId = UserTokenUtil.tokenDecrypt(token, MINI_PROGRAM_USER_TOKEN_KEY);
                List<AppUserOwnProjectVO> userOwnProjectsInfo = iAppRegisterServiceClient.getUserOwnProjectsInfo(userId, "-1");
                boolean guestFlag = true;
                if (userOwnProjectsInfo != null && !userOwnProjectsInfo.isEmpty()) {
                    for (AppUserOwnProjectVO appUserOwnProjectVO : userOwnProjectsInfo) {
                        if (appUserOwnProjectVO.getProjectId().equals(data.get("projectId").toString())) {
                            guestFlag = false;
                            break;
                        }
                    }
                }
                if (guestFlag) {
                    // 保存或修改游客项目历史数据
                    GuestUserHistoryPO guestUserHistoryPO = new GuestUserHistoryPO();
                    guestUserHistoryPO.setUserId(userId);
                    guestUserHistoryPO.setProjectId(data.get("projectId").toString());
                    guestUserHistoryPO.setSource(2);
                    iAppRegisterServiceClient.saveOrUpdateGuestProject(guestUserHistoryPO);
                }
            }
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), data);
        } catch (Exception e) {
            throw new DataAccessException("【小程序_通行版块】定位获取项目失败",e);
        }
    }

    /**
     * <desc>
     *      根据项目编号获取云电梯状态
     * </desc>
     *
     * @param projectId 项目编号
     * @return
     * @author Qiang.S
     * @createDate 2018/11/19
     */
    @RequestMapping(value = "/getIsCloudElevator",method = RequestMethod.POST)
    @ResponseBody
    public Object getIsCloudElevator(String projectId, String createTime, String sign){
        MessageVO messageVO;
        try{
            HttpServletRequest request= ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            projectId=request.getAttribute("projectId")==null?null:request.getAttribute("projectId").toString();
            createTime=request.getAttribute("createTime")==null?null:request.getAttribute("createTime").toString();
            sign=request.getAttribute("sign")==null?null:request.getAttribute("sign").toString();
            //合法性验证
            if (StringUtils.isBlank(projectId)){
                return new MessageVO(MiniProgramErrorCodeEnum.PROJECT_ID_EMPTY_ERR.getErrorCode());
            }
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("projectId",projectId);
            params.put("createTime",createTime);
            //验证签名
            if(!Md5EncryptUtil.checkAppSignValue(params,sign,MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY)){
                return new MessageVO(MiniProgramErrorCodeEnum.MINI_PROGRAM_SIGN_ERR.getErrorCode());
            }
            OperateProjectDetailVO operateProjectDetailVO = iOperateProjectServiceClient.getDetail(projectId);
            Map<String,Object> data=new HashMap<>();
            if (operateProjectDetailVO != null) {
                data.put("isCloudElevator",operateProjectDetailVO.getIsCloudElevator());
            }
            messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),data);
        }catch ( Exception e){
            throw new DataAccessException("【小程序_通行版块】查询是否开通云电梯失败",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      生成二维码
     * </desc>
     *
     * @param projectId 项目编号
     * @return
     * @author Qiang.S
     * @createDate 2018/11/19
     */
    @LoggerInfo(operateDesc = LogDescConstant.CREATE_QRCODE)
    @RequestMapping(value = "/createQrcodeUrl",method = RequestMethod.POST)
    @ResponseBody
    public Object createQrcodeUrl(String projectId,String roomId,String token, String createTime, String sign){
        MessageVO messageVO;
        try{
            HttpServletRequest request= ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            projectId=request.getAttribute("projectId")==null?null:request.getAttribute("projectId").toString();
            token=request.getAttribute("token")==null?null:request.getAttribute("token").toString();
            createTime=request.getAttribute("createTime")==null?null:request.getAttribute("createTime").toString();
            sign=request.getAttribute("sign")==null?null:request.getAttribute("sign").toString();
            roomId = request.getAttribute("roomId")==null?null:request.getAttribute("roomId").toString();
            //合法性验证
            if (StringUtils.isBlank(projectId)){
                return new MessageVO(MiniProgramErrorCodeEnum.PROJECT_ID_EMPTY_ERR.getErrorCode());
            }
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("projectId",projectId);
            params.put("roomId",roomId);
            params.put("createTime",createTime);
            //验证签名
            if(!Md5EncryptUtil.checkAppSignValue(params,sign,MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY)){
                return new MessageVO(MiniProgramErrorCodeEnum.MINI_PROGRAM_SIGN_ERR.getErrorCode());
            }
            ///解密拿到userId
            String userId = UserTokenUtil.tokenDecrypt(token, MINI_PROGRAM_USER_TOKEN_KEY);
            //更新用户二维码
            iAppDeviceServiceClient.setUserQrCode(userId,projectId,roomId);

            messageVO=new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),iAppMineServiceClient.getUserQrcode(projectId,userId,roomId));
        }catch ( Exception e){
            throw new DataAccessException("【小程序_通行版块】生成二维码失败",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      获取当前时间某项目允许推送的公告消息
     * <desc/>
     *
     * @param projectId 项目id
     * @param sign 签名
     * @return
     * @author Qiang.S
     * @createDate 2018-11-19
     */
    @RequestMapping(value = "/getLatestPushTitle",method = RequestMethod.POST)
    @ResponseBody
    public Object getLatestPushTitle(String projectId,String createTime, String sign){
        try {
            HttpServletRequest request= ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            projectId=request.getAttribute("projectId")==null?null:request.getAttribute("projectId").toString();
            createTime=request.getAttribute("createTime")==null?null:request.getAttribute("createTime").toString();
            sign=request.getAttribute("sign")==null?null:request.getAttribute("sign").toString();
            //合法性验证
            if (StringUtils.isBlank(projectId)){
                return new MessageVO(MiniProgramErrorCodeEnum.PROJECT_ID_EMPTY_ERR.getErrorCode());
            }
            //验证签名
            Map<String,String> params = new HashMap<>();
            params.put("projectId",projectId);
            params.put("createTime",createTime);
            if(!Md5EncryptUtil.checkAppSignValue(params,sign,MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY)){
                return  new MessageVO(MiniProgramErrorCodeEnum.MINI_PROGRAM_SIGN_ERR.getErrorCode());
            }
            List<String> propertyNotice = iOperatePushInfoServiceClient.getLatestPushTitle(projectId);
            Map<String, Object> resultMap = new HashMap<>();
            if (propertyNotice == null){
                propertyNotice = new ArrayList<>();
            }

            resultMap.put("propertyNotice", propertyNotice);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), resultMap);
        }catch (Exception e){
            throw new DataAccessException("【小程序_通行】获取项目公告失败", e);
        }
    }



    /**
     * <desc>
     *      查询用户项目状态
     * <desc/>
     *
     * @param projectId 项目id
     * @param sign 签名
     * @return
     * @author Qiang.S
     * @createDate 2018-12-25
     */
    @RequestMapping(value = "/getAppUserProjectStatus",method = RequestMethod.POST)
    @ResponseBody
    public Object getAppUserProjectStatus(String projectId,String token, String createTime, String sign){
        try {
            HttpServletRequest request= ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            projectId=request.getAttribute("projectId")==null?null:request.getAttribute("projectId").toString();
            token=request.getAttribute("token")==null?null:request.getAttribute("token").toString();
            createTime=request.getAttribute("createTime")==null?null:request.getAttribute("createTime").toString();
            sign=request.getAttribute("sign")==null?null:request.getAttribute("sign").toString();
            //合法性验证
            if (StringUtils.isBlank(projectId)){
                return new MessageVO(MiniProgramErrorCodeEnum.PROJECT_ID_EMPTY_ERR.getErrorCode());
            }
            //验证签名
            Map<String,String> params = new HashMap<>();
            params.put("projectId",projectId);
            params.put("createTime",createTime);
            if(!Md5EncryptUtil.checkAppSignValue(params,sign,MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY)){
                return  new MessageVO(MiniProgramErrorCodeEnum.MINI_PROGRAM_SIGN_ERR.getErrorCode());
            }
            ///解密拿到userId
            String userId = UserTokenUtil.tokenDecrypt(token, MINI_PROGRAM_USER_TOKEN_KEY);
            Integer userProjectStatus = iAppMineServiceClient.getAppUserProjectStatus(userId,projectId);
            String status = iAppMineServiceClient.getProjectStatus(projectId);
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("status", status);
            resultMap.put("userProjectStatus", userProjectStatus);

            //获取用户是否是vip
            boolean isVip = iAppMineServiceClient.appUserIsVip(userId,projectId);
            resultMap.put("isVip", isVip?1:0);
            //设置项目云服务费是否过期
            if ("1".equals(status)) {
                String deviceEndTime = iMiniProgramEquipServiceClient.getUserDeviceExpiredInfo(userId,projectId);
                OperateBusinessChargeDTO operateBusinessChargeDTO = new OperateBusinessChargeDTO();
                operateBusinessChargeDTO.setProjectId(projectId);
                OperatePropertyInformationGetVO operatePropertyInformationGetVO = iOperateBusinessChargeServiceClient.getPropertyInformation(operateBusinessChargeDTO);
                if(operatePropertyInformationGetVO!=null){
                    String propertyPhone = operatePropertyInformationGetVO.getPropertyPhone();
                    if(StringUtils.isEmpty(propertyPhone)){
                        propertyPhone = "";
                    }
                    resultMap.put("administratorPhone", propertyPhone);
                    resultMap.put("deviceEndTimeStatus", deviceEndTime);
                }else{
                    resultMap.put("administratorPhone", "");
                    resultMap.put("deviceEndTimeStatus", "");
                }

            }
            //根据userId和projectId查询该用户是否欠费
            if(iAppRegisterServiceClient.getUserIsForbidden(projectId,userId)>0){
                resultMap.put("forbidden", "1");
            }else{
                resultMap.put("forbidden", "0");
            }
            ProjectPO oneProject = iOperateProjectServiceClient.getOneProject(projectId);
            resultMap.put("propertyValueOpen", oneProject.getPropertyValueOpen());
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), resultMap);
        }catch (Exception e){
            throw new DataAccessException("【小程序_通行】查询用户项目状态失败", e);
        }
    }

    /**
     * <desc>
     *      查询小程序全部欠费账单
     * <desc/>
     *
     * @param projectId 项目编号
     * @return MessageVO 标准格式化响应结果
     * @author Qiang.S
     * @createDate 2019/06/03
     */
    @RequestMapping(path = "getAllArrearsBill")
    @ResponseBody
    public Object getAllArrearsBill(String projectId, String token,String createTime,String sign) {
        try {
            HttpServletRequest request= ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            projectId=request.getAttribute("projectId")==null?null:request.getAttribute("projectId").toString();
            token=request.getAttribute("token")==null?null:request.getAttribute("token").toString();
            createTime=request.getAttribute("createTime")==null?null:request.getAttribute("createTime").toString();
            sign=request.getAttribute("sign")==null?null:request.getAttribute("sign").toString();
            Map<String, String> params = new HashMap<>();
            params.put("projectId", projectId);
            params.put("createTime", createTime);
            //验证签名
            if (!Md5EncryptUtil.checkAppSignValue(params, sign, MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY)) {
                return new MessageVO(MiniProgramErrorCodeEnum.MINI_PROGRAM_SIGN_ERR.getErrorCode());
            }
            //项目编号判断
            if (StringUtils.isBlank(projectId)) {
                return new MessageVO(MiniProgramErrorCodeEnum.PROJECT_ID_EMPTY_ERR.getErrorCode());
            }
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), iPropertyAccountServiceClient.getAllArrearsBillForMini(projectId, userCache.retrieve(token).getUserId()));
        } catch (Exception e) {
            throw new DataAccessException(String.format(
                    "【小程序_物业增值_查询全部欠费账单】查询全部欠费账单失败"), e);
        }
    }

    /**
     * <desc>
     *      查询用户历史账单
     * <desc/>
     *
     * @param projectId 项目编号
     * @param roomId 房间编号
     * @return MessageVO 标准格式化响应结果
     * @author Qiang.S
     * @createDate 2019/05/28
     */
    @RequestMapping(path = "getUserBillListH5")
    @ResponseBody
    public Object getUserBillListH5(String projectId, String roomId, String createTime,String sign) {
        try {
            HttpServletRequest request= ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            projectId=request.getAttribute("projectId")==null?null:request.getAttribute("projectId").toString();
            roomId=request.getAttribute("roomId")==null?null:request.getAttribute("roomId").toString();
            createTime=request.getAttribute("createTime")==null?null:request.getAttribute("createTime").toString();
            sign=request.getAttribute("sign")==null?null:request.getAttribute("sign").toString();

            Map<String, String> params = new HashMap<>();
            params.put("projectId", projectId);
            params.put("roomId", roomId);
            params.put("createTime", createTime);
            //验证签名
            if (!Md5EncryptUtil.checkAppSignValue(params, sign, MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY)) {
                return new MessageVO(MiniProgramErrorCodeEnum.MINI_PROGRAM_SIGN_ERR.getErrorCode());
            }
            //项目编号判断
            if (StringUtils.isBlank(projectId)){
                return new MessageVO(MiniProgramErrorCodeEnum.PROJECT_ID_EMPTY_ERR.getErrorCode());
            }
            if (StringUtils.isBlank(roomId)){
                return new MessageVO(MiniProgramErrorCodeEnum.VISIT_ROOM_IS_NULL.getErrorCode());
            }
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), iPropertyAccountServiceClient.getUserBillListH5(projectId,roomId));
        } catch (Exception e) {
            throw new DataAccessException(String.format(
                    "【小程序_物业增值_查询用户历史账单】查询用户历史账单失败"), e);
        }
    }

    /**
     * <desc>
     *      iot开门
     * </desc>
     *
     * @param deviceUnique 设备序列号
     * @param token 用户凭证
     * @param createTime 时间戳 参与签名
     * @param sign 签名
     *
     * @return
     * @author Qiang.S
     * @createDate 2019/03/18
     */
    @ResponseBody
    @RequestMapping("/netOpenDoor")
    @LoggerInfo(operateDesc = LogDescConstant.REMOTE_OPEN_DOOR)
    public Object netOpenDoor(String deviceUnique,String correlationId,String token,String createTime,String sign) throws Exception{
        try {
            HttpServletRequest request= ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            deviceUnique=request.getAttribute("deviceUnique")==null?null:request.getAttribute("deviceUnique").toString();
            correlationId=request.getAttribute("correlationId")==null?null:request.getAttribute("correlationId").toString();
            token=request.getAttribute("token")==null?null:request.getAttribute("token").toString();
            createTime=request.getAttribute("createTime")==null?null:request.getAttribute("createTime").toString();
            sign=request.getAttribute("sign")==null?null:request.getAttribute("sign").toString();

            Map<String,String> params = new HashMap<>();
            params.put("deviceUnique",deviceUnique);
            params.put("correlationId",correlationId);
            params.put("createTime",createTime);
            //验证签名
            if(!Md5EncryptUtil.checkAppSignValue(params,sign,MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY)){
                return  new MessageVO(MiniProgramErrorCodeEnum.MINI_PROGRAM_SIGN_ERR.getErrorCode());
            }
            //查询项目远程开门配置是否为启用 关闭则直接返回
            Integer networkOpen = iAppProjectServiceClient.getNetworkOpenSetting(StringHandlerUtil.getProjectIdByDeviceUnique(deviceUnique));
            if(DataStatusEnum.DELETE.getType()==networkOpen){
                return new MessageVO(AppErrorCodeEnum.CLOUD_ENTRANCE_NETWORK_OPEN_IS_CLOSED.getErrorCode());
            }
            //查询门禁设备的iot账号及绑定的iot产品key
            Map<String,Object> entrance = iCloudEntranceServiceClient.getMainDeviceUniqueAndProductKey(deviceUnique);
            Map<String,Object> result = new HashMap<>();
            if(entrance != null && entrance.get("deviceUnique") != null) {
                AppUserCacheVO userInfoPO = userCache.retrieve(token);
                iCloudEntranceServiceClient.entranceOpenOrCloseCtrl("itlong", entrance.get("deviceUnique").toString(),
                        Integer.valueOf(deviceUnique.substring(deviceUnique.length() - 4, deviceUnique.length())).toString(),
                        CloudEntranceOpenTypeEnum.OPEN.getType().toString(), "1", entrance.get("productKey").toString(), userInfoPO.getUserId(), correlationId,"0");
                //判断电梯当前状态是否是开门，如果是开门则返回成功，否则返回失败
                int doorStatus = 2;
                String isOnline = iIotServerServiceClient.batchGetDeviceState(entrance.get("productKey").toString(),entrance.get("deviceUnique").toString());
                if (isOnline != null && !isOnline.equals(IotDeviceStatusEnum.ONLINE.getType())) {
                    result.put("doorStatus",0);
                    return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),result);
                }
                int count = 0;
                while(count<10){
                    Thread.sleep(500);
                    IotCloudEntranceStateDTO dto = JsonUtil.toObject(redisService.getKeysForDevice(RedisConstant.REDIS_IOT_CLOUD_ENTRANCE_STATE_CACHE +
                            deviceUnique), IotCloudEntranceStateDTO.class);
                    if(dto != null && dto.getMsgCode() == 0){
                        doorStatus = 1;
                        break;
                    }
                    count++;
                }
                result.put("doorStatus",doorStatus);
            }else{
                result.put("doorStatus",0);
            }
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),result);
        }catch (Exception e){
            throw new DataAccessException("【小程序_通行版块】远程开门失败",e);
        }
    }

    /**
     * <desc>
     *      用户微信扫描二维码之后进行iot开门或呼梯
     * </desc>
     *
     * @author wangzhi
     * @createDate 2020/02/25
     */
    @ResponseBody
    @RequestMapping("/openDoorOrCallElevatorByScanQrCode")
    @LoggerInfo(operateDesc = LogDescConstant.OPEN_DOOR_OR_CALL_ELEVATOR_BY_SCAN_QRCODE)
    public Object netOpenDoorByScanQrCode() throws Exception{
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            MiniScanQrCodePassDTO miniScanQrCodePassDTO = HttpProtocolUtil.parseRequestParamToDTO(MiniScanQrCodePassDTO.class, request);
            String token = request.getAttribute("token") == null ? null : request.getAttribute("token").toString();
            String sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
            // 参数校验
            if (miniScanQrCodePassDTO == null || StringUtils.isBlank(miniScanQrCodePassDTO.getCode()) || StringUtils.isBlank(token)
                    || StringUtils.isBlank(miniScanQrCodePassDTO.getCorrelationId())/* || !NumberHandlerUtil.isInRange(miniScanQrCodePassDTO.getType(), 1, 3)*/) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }

            //验证签名
            if (!Md5EncryptUtil.checkAppSignValue(miniScanQrCodePassDTO, sign, MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY)) {
                return new MessageVO(MiniProgramErrorCodeEnum.MINI_PROGRAM_SIGN_ERR.getErrorCode());
            }

            // 第二次请求，校验参数（优化逻辑后无第二次请求）
//            if (NumberHandlerUtil.isInRange(miniScanQrCodePassDTO.getType(), 2, 3) &&
//                    (StringUtils.isBlank(miniScanQrCodePassDTO.getProjectId()) || StringUtils.isBlank(miniScanQrCodePassDTO.getDeviceUnique()))) {
//                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
//            }
//            if (miniScanQrCodePassDTO.getType() == 2 && (StringUtils.isBlank(miniScanQrCodePassDTO.getFromFloor()) || StringUtils.isBlank(miniScanQrCodePassDTO.getToFloor()))) {
//                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
//            }
//            if (miniScanQrCodePassDTO.getType() == 3 && StringUtils.isBlank(miniScanQrCodePassDTO.getLogicalFloor())) {
//                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
//            }

            // 获取二维码相关信息，包含绑定的设备
            OperateDeviceQRCodeInfoVO operateDeviceQRCodeInfoVO = iMiniProgramEquipServiceClient.getQrCodeInfo(miniScanQrCodePassDTO);
            if (operateDeviceQRCodeInfoVO == null) {
                return new MessageVO(BaseErrorCodeEnum.ERROR.getErrorCode(), "该二维码尚未正确绑定设备或不存在此环境或已被禁用");
            }
            // 获取电梯的公共楼层
            Map<String, Object> elevatorCommonMap = null;
            if ("1".equals(operateDeviceQRCodeInfoVO.getDeviceType())) {
                elevatorCommonMap = iMiniProgramEquipServiceClient.getElevatorCommonFloor(operateDeviceQRCodeInfoVO.getDeviceUnique());
            }
            if (elevatorCommonMap == null) {
                elevatorCommonMap = new HashMap<>();
            }

            String projectId = operateDeviceQRCodeInfoVO.getProjectId();
            // 校验项目状态
            ProjectPO oneProject = iOperateProjectServiceClient.getOneProject(projectId);
            if (oneProject == null) {
                return new MessageVO(BaseErrorCodeEnum.ERROR.getErrorCode(), "项目不存在或项目已被删除");
            }
            if (oneProject.getStatus() == 2) {
                return new MessageVO(MiniProgramErrorCodeEnum.PROJECT_IS_BANNED.getErrorCode());
            }
            AppUserCacheVO userInfoPO = userCache.retrieve(token);
            //获取用户是否是vip
            boolean isVipBoolean = iAppMineServiceClient.appUserIsVip(userInfoPO.getUserId(),projectId);
            int  isVip  = isVipBoolean?1:0;
            // 校验用户项目状态
            Integer userProjectStatus = iAppMineServiceClient.getAppUserProjectStatus(userInfoPO.getUserId(), projectId);
            if (userProjectStatus == null) {
                ///解密拿到userId
                String userId = UserTokenUtil.tokenDecrypt(token, MINI_PROGRAM_USER_TOKEN_KEY);
                //如果该用户在小区没有房屋，则需查询code所绑定设备的房屋相关信息
                MiniProgramUserRoomInfoVO roomInfoVO = new MiniProgramUserRoomInfoVO();
                List<MiniProgramUserRoomInfoVO> roomInfoVOList = iMiniProgramEquipServiceClient.getAddressByDeviceUnique(operateDeviceQRCodeInfoVO.getDeviceUnique());
                if (!roomInfoVOList.isEmpty()) {
                    //查询该用户是否为纯访客，在所有项目下没有房间
                    List<AppUserOwnProjectVO> projectVOList = iAppRegisterServiceClient.getUserOwnProjectsInfo(userId,"-1");
                    if(projectVOList.isEmpty()){
                        roomInfoVO.setVisitorMark("1");
                    }else{
                        roomInfoVO.setVisitorMark("2");
                    }
                    List<Map<String,String>> mapList = new ArrayList<>();
                    roomInfoVO.setProjectName(roomInfoVOList.get(0).getProjectName());
                    roomInfoVO.setProvince(roomInfoVOList.get(0).getProvince());
                    roomInfoVO.setCityId(roomInfoVOList.get(0).getCityId());
                    roomInfoVO.setCityName(roomInfoVOList.get(0).getCityName());
                    roomInfoVO.setProjectId(projectId);
                    roomInfoVO.setOperateType("2".equals(operateDeviceQRCodeInfoVO.getDeviceType()) ? "3" : (operateDeviceQRCodeInfoVO.getSedanPlace() == 1 ? "1" : "2"));
                    roomInfoVO.setOpenGuestMode(operateDeviceQRCodeInfoVO.getOpenGuestMode());
                    roomInfoVO.setCommonLogicalFloor(elevatorCommonMap.get("commonLogicalFloor") == null ? "" : elevatorCommonMap.get("commonLogicalFloor").toString());
                    roomInfoVO.setCommonFloor(elevatorCommonMap.get("commonNaturalFloor") == null ? "" : elevatorCommonMap.get("commonNaturalFloor").toString());
                    roomInfoVO.setFloorAuth(StringHandlerUtil.filterLastComma(StringHandlerUtil.getAuthCodeBynNturalFloors("")).toUpperCase());
                    roomInfoVO.setGroupConId(operateDeviceQRCodeInfoVO.getGroupConId() == null ? "" : operateDeviceQRCodeInfoVO.getGroupConId());
                    roomInfoVO.setDeviceName(operateDeviceQRCodeInfoVO.getDeviceName());
                    roomInfoVO.setDeviceUnique(operateDeviceQRCodeInfoVO.getDeviceUnique());
                    roomInfoVO.setQrCodeFloor(operateDeviceQRCodeInfoVO.getQrCodeFloor());
                    roomInfoVO.setDeviceKind(operateDeviceQRCodeInfoVO.getDeviceKind());
                    roomInfoVO.setPubKey(operateDeviceQRCodeInfoVO.getPubKey());
                    //处理楼栋门禁和单元设备
                    for(MiniProgramUserRoomInfoVO infoVO : roomInfoVOList){
                        Map<String,String> map = new HashMap<>();
                        map.put("buildId",infoVO.getBuildId());
                        map.put("buildName",infoVO.getBuildName());
                        mapList.add(map);
                    }
                    roomInfoVO.setBuildInfo(mapList);
                    if(StringUtils.isNotEmpty(roomInfoVOList.get(0).getUnitId())){
                        //此处处理单元设备
                        roomInfoVO.setUnitInfo(iMiniProgramEquipServiceClient.getUnitInfoByBuildId(roomInfoVOList.get(0).getBuildId(),operateDeviceQRCodeInfoVO.getDeviceUnique()));
                    }
                    return new MessageVO(MiniProgramErrorCodeEnum.USER_IN_PROJECT_NO_ROOM.getErrorCode(), roomInfoVO);
                }
                return new MessageVO(BaseErrorCodeEnum.ERROR.getErrorCode(), "您不是该小区住户");
            }
            if (userProjectStatus == 0) {
                return new MessageVO(BaseErrorCodeEnum.ERROR.getErrorCode(), "您的该小区身份已被冻结");
            }
            // 校验物业增值状态
            //根据userId和projectId查询该用户是否欠费
            if (iAppRegisterServiceClient.getUserIsForbidden(projectId, userInfoPO.getUserId()) > 0) {
                return new MessageVO(BaseErrorCodeEnum.ERROR.getErrorCode(), "您有物业费用未缴，开门功能已禁用");
            }
            List<MiniProgramMyEquipListVO> miniProgramMyEquipListVOS = iMiniProgramEquipServiceClient.myEquipInfo(userInfoPO.getUserId(), projectId);
            // 循环时顺便构建要返回的参数
            MiniScanQrCodePassVO miniScanQrCodePassVO = new MiniScanQrCodePassVO();
            miniScanQrCodePassVO.setIsVip(isVip);
            miniScanQrCodePassVO.setProjectName(operateDeviceQRCodeInfoVO.getProjectName());
            miniScanQrCodePassVO.setPubKey(operateDeviceQRCodeInfoVO.getPubKey());
            miniScanQrCodePassVO.setIsFaceRecognition(operateDeviceQRCodeInfoVO.getIsFaceRecognition());
            miniScanQrCodePassVO.setBluetoothCall(operateDeviceQRCodeInfoVO.getBluetoothCall());
            miniScanQrCodePassVO.setOpenGuestMode(operateDeviceQRCodeInfoVO.getOpenGuestMode());
            miniScanQrCodePassVO.setGroupConId(operateDeviceQRCodeInfoVO.getGroupConId() == null ? "" : operateDeviceQRCodeInfoVO.getGroupConId());
            miniScanQrCodePassVO.setDeviceUnique(operateDeviceQRCodeInfoVO.getDeviceUnique());
            miniScanQrCodePassVO.setDeviceName(operateDeviceQRCodeInfoVO.getDeviceName());
            miniScanQrCodePassVO.setProvince(operateDeviceQRCodeInfoVO.getProvince());
            miniScanQrCodePassVO.setCityName(operateDeviceQRCodeInfoVO.getCityName());
            miniScanQrCodePassVO.setCityId(operateDeviceQRCodeInfoVO.getCityId());
            miniScanQrCodePassVO.setDeviceKind(operateDeviceQRCodeInfoVO.getDeviceKind());
            boolean haveDevice = false;
            for (MiniProgramMyEquipListVO miniProgramMyEquipListVO : miniProgramMyEquipListVOS) {
                if (operateDeviceQRCodeInfoVO.getDeviceUnique().equals(miniProgramMyEquipListVO.getDeviceUnique())) {
                    miniScanQrCodePassVO.setProjectId(projectId);
                    miniScanQrCodePassVO.setFloorAuth(miniProgramMyEquipListVO.getFloorAuth());
                    miniScanQrCodePassVO.setLiveFloor(miniProgramMyEquipListVO.getLiveFloor());
                    miniScanQrCodePassVO.setLiveLogicalFloor(miniProgramMyEquipListVO.getLiveLogicalFloor());
                    miniScanQrCodePassVO.setCommonFloor(miniProgramMyEquipListVO.getCommonFloor());
                    miniScanQrCodePassVO.setCommonLogicalFloor(miniProgramMyEquipListVO.getCommonLogicalFloor());
                    miniScanQrCodePassVO.setFloors(miniProgramMyEquipListVO.getFloors());
                    miniScanQrCodePassVO.setFloorsName(miniProgramMyEquipListVO.getFloorsName());
                    haveDevice = true;
                    break;
                }
            }
            // 用户无该设备权限，但是开通了游客模式且有公共楼层的电梯设备
            if (StringUtils.isBlank(miniScanQrCodePassVO.getProjectId()) && "1".equals(operateDeviceQRCodeInfoVO.getDeviceType())
                    && "1".equals(operateDeviceQRCodeInfoVO.getOpenGuestMode()) && elevatorCommonMap.get("commonLogicalFloor") != null) {
                // 先判断该设备云服务费是否过期
                List<Map<String, Object>> cloudServiceMapList = iAppPadFaceServiceClient.getDeviceCloudServiceCostEndTime(projectId);
                String projectMinEndTime = iAppDeviceServiceClient.getProjectCloudServiceCostMinEndTime(projectId);
                Long overDay = null;
                SimpleDateFormat sdf = new SimpleDateFormat(DateUtil.YMDSQL);
                Date nowTime = sdf.parse(sdf.format(new Date()));
                for (Map<String, Object> cloudServiceMap : cloudServiceMapList) {
                    if (cloudServiceMap.get("deviceUnique") != null && operateDeviceQRCodeInfoVO.getDeviceUnique().equals(cloudServiceMap.get("deviceUnique").toString())) {
                        overDay = (nowTime.getTime() - sdf.parse(cloudServiceMap.get("endTime").toString()).getTime()) / (24 * 60 * 60 * 1000);
                        break;
                    }
                }
                if (overDay == null) {
                    // 云服务费设备过期时间如果为空,就用项目过期时间
                    overDay = (nowTime.getTime() - sdf.parse(projectMinEndTime).getTime()) / (24 * 60 * 60 * 1000);
                }
                if (overDay > 3) {
                    return new MessageVO(BaseErrorCodeEnum.ERROR.getErrorCode(), "该设备云服务费已过期");
                }
                miniScanQrCodePassVO.setProjectId(projectId);
                miniScanQrCodePassVO.setFloorAuth(StringHandlerUtil.filterLastComma(StringHandlerUtil.getAuthCodeBynNturalFloors("")).toUpperCase());
                miniScanQrCodePassVO.setLiveFloor("");
                miniScanQrCodePassVO.setLiveLogicalFloor("");
                miniScanQrCodePassVO.setCommonFloor(elevatorCommonMap.get("commonNaturalFloor").toString());
                miniScanQrCodePassVO.setCommonLogicalFloor(elevatorCommonMap.get("commonLogicalFloor").toString());
                miniScanQrCodePassVO.setFloors(elevatorCommonMap.get("commonNaturalFloor").toString());
                miniScanQrCodePassVO.setFloorsName(elevatorCommonMap.get("commonLogicalFloor").toString());
                haveDevice = true;
            }
            if (!haveDevice) {
                return new MessageVO(BaseErrorCodeEnum.ERROR.getErrorCode(), "您没有该设备权限或该设备云服务费已过期");
            }

            if (/*miniScanQrCodePassDTO.getType() == 1 && */"2".equals(operateDeviceQRCodeInfoVO.getDeviceType())) {
                // 扫码之后第一次请求，二维码绑定的是云门禁，直接开门
                //查询门禁设备的iot账号及绑定的iot产品key
                Map<String, Object> entrance = iCloudEntranceServiceClient.getMainDeviceUniqueAndProductKey(operateDeviceQRCodeInfoVO.getDeviceUnique());
                Map<String, Object> result = new HashMap<>();
                result.put("apiStatus", "1");
                result.put("isVip", isVip);
                result.put("deviceUnique", operateDeviceQRCodeInfoVO.getDeviceUnique());
                result.put("deviceName", operateDeviceQRCodeInfoVO.getDeviceName());
                result.put("projectId", operateDeviceQRCodeInfoVO.getProjectId());
                result.put("projectName", operateDeviceQRCodeInfoVO.getProjectName());
                result.put("pubKey", operateDeviceQRCodeInfoVO.getPubKey());
                result.put("isFaceRecognition", operateDeviceQRCodeInfoVO.getIsFaceRecognition());
                result.put("bluetoothCall", operateDeviceQRCodeInfoVO.getBluetoothCall());
                result.put("openGuestMode", operateDeviceQRCodeInfoVO.getOpenGuestMode());
                result.put("province", operateDeviceQRCodeInfoVO.getProvince());
                result.put("cityName", operateDeviceQRCodeInfoVO.getCityName());
                result.put("cityId", operateDeviceQRCodeInfoVO.getCityId());
                if (entrance != null && entrance.get("deviceUnique") != null) {
                    iCloudEntranceServiceClient.entranceOpenOrCloseCtrl("itlong", entrance.get("deviceUnique").toString(),
                            Integer.valueOf(operateDeviceQRCodeInfoVO.getDeviceUnique().substring(operateDeviceQRCodeInfoVO.getDeviceUnique().length() - 4,
                                    operateDeviceQRCodeInfoVO.getDeviceUnique().length())).toString(),
                            CloudEntranceOpenTypeEnum.OPEN.getType().toString(), "1", entrance.get("productKey").toString(), userInfoPO.getUserId(),
                            miniScanQrCodePassDTO.getCorrelationId(), "0");
                    //判断当前状态是否是开门，如果是开门则返回成功，否则返回失败
                    int doorStatus = 2;
                    String isOnline = iIotServerServiceClient.batchGetDeviceState(entrance.get("productKey").toString(), entrance.get("deviceUnique").toString());
                    if (isOnline != null && !isOnline.equals(IotDeviceStatusEnum.ONLINE.getType())) {
                        result.put("doorStatus", 0);
                        return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), result);
                    }
                    int count = 0;
                    while (count < 10) {
                        Thread.sleep(500);
                        IotCloudEntranceStateDTO dto = JsonUtil.toObject(redisService.getKeysForDevice(RedisConstant.REDIS_IOT_CLOUD_ENTRANCE_STATE_CACHE +
                                operateDeviceQRCodeInfoVO.getDeviceUnique()), IotCloudEntranceStateDTO.class);
                        if (dto != null && dto.getMsgCode() == 0) {
                            doorStatus = 1;
                            break;
                        }
                        count++;
                    }
                    result.put("doorStatus", doorStatus);
                } else {
                    result.put("doorStatus", 0);
                }
                return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), result);
            } else if (/*miniScanQrCodePassDTO.getType() == 1 && */"1".equals(operateDeviceQRCodeInfoVO.getDeviceType())) {
                // 扫码之后第一次请求，二维码绑定的是云电梯，返回相关参数
                miniScanQrCodePassVO.setApiStatus("2");
                miniScanQrCodePassVO.setType(operateDeviceQRCodeInfoVO.getSedanPlace().toString());
                miniScanQrCodePassVO.setQrCodeFloor(operateDeviceQRCodeInfoVO.getQrCodeFloor());
                boolean haveFloor = true;
                if (StringUtils.isNotBlank(operateDeviceQRCodeInfoVO.getQrCodeFloor()) && operateDeviceQRCodeInfoVO.getSedanPlace() == 2) {
                    List<String> floorList = StringHandlerUtil.splitStringList(miniScanQrCodePassVO.getLiveLogicalFloor());
                    List<String> floorCommonList = StringHandlerUtil.splitStringList(miniScanQrCodePassVO.getCommonLogicalFloor());
                    floorList.addAll(floorCommonList);
                    haveFloor = floorList.contains(miniScanQrCodePassVO.getQrCodeFloor());
                }
                if (!haveFloor) {
                    return new MessageVO(BaseErrorCodeEnum.ERROR.getErrorCode(), "您没有当前楼层权限");
                }
            }/* else if (miniScanQrCodePassDTO.getType() == 2 && "1".equals(operateDeviceQRCodeInfoVO.getDeviceType())) {
                // 扫码之后选完楼层轿外呼梯
                MiniCallLiftDTO miniCallLiftDTO = new MiniCallLiftDTO();
                miniCallLiftDTO.setDeviceUnique(miniScanQrCodePassDTO.getDeviceUnique());

                miniScanQrCodePassVO.setApiStatus("3");
            } else if (miniScanQrCodePassDTO.getType() == 3 && "1".equals(operateDeviceQRCodeInfoVO.getDeviceType())) {
                // 扫码之后选完楼层轿内呼梯

                miniScanQrCodePassVO.setApiStatus("3");
            } */else {
                return new MessageVO(BaseErrorCodeEnum.ERROR.getErrorCode(), "此次操作无效，请重新扫码"); // 无效原因可能是选择楼层期间二维码进行了重新绑定
            }
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), miniScanQrCodePassVO);
        } catch (Exception e) {
            throw new DataAccessException("【小程序_通行版块】扫码通行失败", e);
        }
    }

    /**
     * <desc>
     *      获取访客通行密码邀请记录
     * </desc>
     *
     * @return 标准格式化响应结果
     * @author Juguang.S
     * @createDate 2019/08/27
     */
    @ResponseBody
    @PostMapping("getInvateRecord")
    public Object getInviteRecord(String projectId, String token, String pageNo, String pageSize, String createTime, String sign){
        try {
            HttpServletRequest request= ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            projectId=request.getAttribute("projectId")==null?null:request.getAttribute("projectId").toString();
            token=request.getAttribute("token")==null?null:request.getAttribute("token").toString();
            pageNo=request.getAttribute("pageNo")==null?null:request.getAttribute("pageNo").toString();
            pageSize=request.getAttribute("pageSize")==null?null:request.getAttribute("pageSize").toString();
            createTime=request.getAttribute("createTime")==null?null:request.getAttribute("createTime").toString();
            sign=request.getAttribute("sign")==null?null:request.getAttribute("sign").toString();
            //验签
            Map<String, String> params = new HashMap<>();
            params.put("projectId", projectId);
            params.put("pageNo", pageNo);
            params.put("pageSize", pageSize);
            params.put("createTime", createTime);
            //验证签名
            if(!Md5EncryptUtil.checkAppSignValue(params,sign,MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY)){
                return  new MessageVO(MiniProgramErrorCodeEnum.MINI_PROGRAM_SIGN_ERR.getErrorCode());
            }

            if (StringUtils.isBlank(projectId) || StringUtils.isBlank(pageNo) || StringUtils.isBlank(token) || StringUtils.isBlank(pageSize)) {
                return new MessageVO(BaseErrorCodeEnumEN.NOT_PARAM.getErrorCode());
            }
            // 从缓存中获取用户信息
            AppUserCacheVO userInfo = (AppUserCacheVO) StringHandlerUtil.formatString(userCache.retrieve(token));
            Map<String, Object> data = iAppDevicePassRecordServiceClient.getInviteRecord(projectId, pageNo, pageSize, userInfo.getUserId());
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), data);
        } catch (Exception e) {
            throw new DataAccessException("【小程序_通行版块】获取访客通行密码邀请记录失败", e);
        }
    }

    /**
     * <desc>
     *      获取通行记录列表，小程序2.0版本新增
     * </desc>
     *
     * @return 标准格式化响应结果
     * @author Juguang.S
     * @createDate 2019/08/27
     */
    @ResponseBody
    @PostMapping("getOpenDoorRecord")
    public Object getOpenDoorRecord(String projectId, String pageIndex, String token, String createTime, String sign){
        try {
            HttpServletRequest request= ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            projectId=request.getAttribute("projectId")==null?null:request.getAttribute("projectId").toString();
            pageIndex=request.getAttribute("pageIndex")==null?null:request.getAttribute("pageIndex").toString();
            token=request.getAttribute("token")==null?null:request.getAttribute("token").toString();
            createTime=request.getAttribute("createTime")==null?null:request.getAttribute("createTime").toString();
            sign=request.getAttribute("sign")==null?null:request.getAttribute("sign").toString();
            //验签
            Map<String, String> params = new HashMap<>();
            params.put("projectId", projectId);
            params.put("pageIndex", pageIndex);
            params.put("createTime", createTime);
            if(!Md5EncryptUtil.checkAppSignValue(params,sign,MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY)){
                return  new MessageVO(MiniProgramErrorCodeEnum.MINI_PROGRAM_SIGN_ERR.getErrorCode());
            }

            if (StringUtils.isBlank(projectId) || StringUtils.isBlank(pageIndex) || StringUtils.isBlank(token)) {
                return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
            }
            // 从缓存中获取用户信息
            AppUserCacheVO userInfo = (AppUserCacheVO) StringHandlerUtil.formatString(userCache.retrieve(token));
            Map<String, Object> data = iAppDevicePassRecordServiceClient.getOpenDoorRecord(projectId, pageIndex, userInfo.getUserId());
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), data);
        } catch (Exception e) {
            throw new DataAccessException("【小程序_通行版块】获取通行记录列表失败", e);
        }
    }

    /**
     * <desc>
     *      获取用户当前项目下的小区通知
     * </desc>
     *
     * @return 标准格式化响应结果
     * @author Juguang.S
     * @createDate 2019/08/28
     */
    @ResponseBody
    @PostMapping("messageBox")
    public Object getMessage(String projectId, String pageNum, String token, String createTime, String sign) {
        try {
            HttpServletRequest request= ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            projectId=request.getAttribute("projectId")==null?null:request.getAttribute("projectId").toString();
            pageNum=request.getAttribute("pageNum")==null?null:request.getAttribute("pageNum").toString();
            token=request.getAttribute("token")==null?null:request.getAttribute("token").toString();
            createTime=request.getAttribute("createTime")==null?null:request.getAttribute("createTime").toString();
            sign=request.getAttribute("sign")==null?null:request.getAttribute("sign").toString();
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("projectId",projectId);
            params.put("pageNum",pageNum);
            params.put("createTime",createTime);
            if(!Md5EncryptUtil.checkAppSignValue(params,sign,MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY)){
                return  new MessageVO(MiniProgramErrorCodeEnum.MINI_PROGRAM_SIGN_ERR.getErrorCode());
            }

            if (StringUtils.isBlank(projectId) || StringUtils.isBlank(pageNum) || StringUtils.isBlank(token)) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            // 从缓存中获取用户信息
            AppUserCacheVO userInfo = (AppUserCacheVO) StringHandlerUtil.formatString(userCache.retrieve(token));
            String url = PROPERTY_MANAGE_WEB_URL + "pushInfo?";
            Map<String, Object> data = iAppProjectServiceClient.getMessageBoxByPropertyAndOperate(projectId, pageNum, userInfo.getUserId(), url);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), data);
        } catch (Exception e) {
            throw new DataAccessException("【小程序_通行版块】获取用户当前项目下的推送消息失败", e);
        }
    }

    /**
     * <desc>
     *      用户读取新消息
     * </desc>
     *
     * @return 标准格式化响应结果
     * @author Juguang.S
     * @createDate 2019/08/28
     */
    @ResponseBody
    @PostMapping("readNewMsg")
    public Object readNewMsg(String msgId, String token, String createTime, String sign) {
        try {
            HttpServletRequest request= ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            msgId=request.getAttribute("msgId")==null?null:request.getAttribute("msgId").toString();
            token=request.getAttribute("token")==null?null:request.getAttribute("token").toString();
            createTime=request.getAttribute("createTime")==null?null:request.getAttribute("createTime").toString();
            sign=request.getAttribute("sign")==null?null:request.getAttribute("sign").toString();
            //验签
            Map<String, String> params = new HashMap<>();
            params.put("msgId", msgId);
            params.put("createTime", createTime);
            if(!Md5EncryptUtil.checkAppSignValue(params,sign,MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY)){
                return  new MessageVO(MiniProgramErrorCodeEnum.MINI_PROGRAM_SIGN_ERR.getErrorCode());
            }

            if (StringUtils.isBlank(msgId) || StringUtils.isBlank(token)) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            // 从缓存中获取用户信息
            AppUserCacheVO userInfo = (AppUserCacheVO) StringHandlerUtil.formatString(userCache.retrieve(token));
            iAppProjectServiceClient.readNewMsg(msgId, userInfo.getUserId());
            Map<String, String> data = new HashMap<>();
            data.put("readCode", "1");
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), data);
        } catch (Exception e) {
            throw new DataAccessException("【小程序_通行版块】用户读取新消息失败", e);
        }
    }

    /**
     * <desc>
     *      获取当前时间某项目允许推送的公告消息 此接口为了版本兼容问题，下个版本此接口可删除
     * <desc/>
     *
     * @param projectId 项目id
     * @param sign 签名
     * @return
     * @author Qiang.S
     * @createDate 2018-11-19
     */
    @RequestMapping(value = "/getBanner",method = RequestMethod.POST)
    @ResponseBody
    public MessageVO getBanner(String projectId,String createTime, String sign){
        try {
            //合法性验证
            if (StringUtils.isBlank(projectId)){
                return new MessageVO(MiniProgramErrorCodeEnum.PROJECT_ID_EMPTY_ERR.getErrorCode());
            }
            //验证签名
            Map<String,String> params = new HashMap<>();
            params.put("projectId",projectId);
            params.put("createTime",createTime);
            if(!Md5EncryptUtil.checkAppSign(params,sign,MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY)){
                return  new MessageVO(MiniProgramErrorCodeEnum.MINI_PROGRAM_SIGN_ERR.getErrorCode());
            }
            List<String> propertyNotice = iOperatePushInfoServiceClient.getLatestPushContent(projectId);
            Map<String, Object> resultMap = new HashMap<>();
            if (propertyNotice == null){
                propertyNotice = new ArrayList<>();
            }

            resultMap.put("propertyNotice", propertyNotice);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), resultMap);
        }catch (Exception e){
            throw new DataAccessException("【小程序_通行】获取项目公告失败", e);
        }
    }
}
